from src.init_all_devices import device_dict
from flask import Flask, jsonify, request, render_template
from flask_cors import CORS
from concurrent.futures.thread import ThreadPoolExecutor
from concurrent.futures import as_completed

app = Flask(__name__)
app.config['CORS_HEADERS'] = 'Content-Type'
CORS(app,  resources={r"/*": {"origins": "*"}})


def global_send_text(data):
    pool = ThreadPoolExecutor(20)
    text = data.get("text")
    if not text or len(str(text).strip()) == 0:
        return jsonify({"code": -1, "msg": "评论文本信息是必填项，请正确输入", "err": "评论文本信息是必填项，请正确输入"})
    device = data.get("device")
    device_list = data.get("deviceList")
    count = data.get("count") or 1
    interval = data.get("interval") or 0.5
    try:
        count = int(count)
        interval = round(float(interval), 1)
    except Exception as e:
        print(e)
        return jsonify({"code": -1, "msg": f"【评论次数】 或 【评论频率】 输入错误", "err": f"【评论次数】 或 【评论频率】 输入错误"})
    if not device_list and not device:
        return jsonify({"code": -1, "msg": "设备端口号不能为空"})
    if device_list and device:
        return jsonify({"code": -1, "msg": f"【批量操作】和【单一操作】只能任选一个，不能都选择", "err": f"【批量操作】和【单一操作】只能任选一个，不能都选择"})

    if device:
        driver = device_dict[device]
        driver.stop = False
        pool.submit(driver.set_text, text, count, interval)
        return jsonify({"code": 0, "msg": "评论操作成功"})

    if device_list:
        for device in device_list:
            driver = device_dict.get(device)
            if driver:
                driver.stop = False
                pool.submit(driver.set_text, text, count, interval)
        return jsonify({"code": 0, "msg": "评论操作成功"})

def global_room_click_like(data):
    pool = ThreadPoolExecutor(20)
    device = data.get("device")
    device_list = data.get("deviceList")
    count = data.get("count") or 1
    interval = data.get("interval") or 1
    try:
        count = int(count)
        interval = round(float(interval), 1)
    except Exception as e:
        print(e)
        return jsonify({"code": -1, "msg": f"【点赞次数】 或 【点赞固定频率】 输入错误", "err": f"【点赞次数】 或 【点赞固定频率】 输入错误"})
    randomInterval = data.get("randomInterval")
    randomInterval_range = []
    if randomInterval:
        cur_range = str(randomInterval).split(",")
        print("range", cur_range)
        if len(cur_range) != 2:
            return jsonify({"code": -1, "msg": "输入错误，点赞随机范围必须是两个数", "err": "输入错误，点赞随机范围必须是两个数"})
        try:
            randomInterval_range.append(int(cur_range[0]))
            randomInterval_range.append(int(cur_range[1]))
        except Exception as e:
            print(e)
            return jsonify({"code": -1, "msg": "输入错误，点赞随机频率必须是数字", "err": "输入错误，点赞随机频率必须是数字"})
    if not device_list and not device:
        return jsonify({"code": -1, "msg": "设备端口号不能为空"})
    if device_list and device:
        return jsonify({"code": -1, "msg": f"【批量操作】和【单一操作】只能任选一个，不能都选择"})

    if device:
        driver = device_dict[device]
        driver.stop = False
        pool.submit(driver.click_like, count, interval, randomInterval_range)
        return jsonify({"code": 0, "msg": "点赞操作成功"})
    if device_list:
        for device in device_list:
            driver = device_dict.get(device)
            if driver:
                driver.stop = False
                pool.submit(driver.click_like, count, interval, randomInterval_range)
        return jsonify({"code": 0, "msg": "批量点赞操作成功"})

def global_find_gift(data):
    pool = ThreadPoolExecutor(20)
    device = data.get("device")
    device_list = data.get("deviceList")
    gift_name = data.get("giftName")
    if not gift_name:
        return jsonify({"code": -1, "msg": f"礼物名称不能为空", "err": f"礼物名称不能为空"})
    giftInterval_list = data.get("giftIntervalList") or []
    count = data.get("giftCount") or 1
    try:
        count = int(count)
        giftInterval_list = list(giftInterval_list)
    except Exception as e:
        print(e)
        return jsonify({"code": -1, "msg": f"【礼物个数】 或 【礼物时间间隔】 输入错误", "err": f"【礼物个数】 或 【礼物时间间隔】 输入错误"})

    if not device_list and not device:
        return jsonify({"code": -1, "msg": "设备端口号不能为空"})
    if device_list and device:
        return jsonify({"code": -1, "msg": f"【批量操作】和【单一操作】只能任选一个，不能都选择"})

    if device:
        driver = device_dict[device]
        driver.stop = False
        pool.submit(driver.find_given_gift, gift_name, count, giftInterval_list)
        return jsonify({"code": 0, "msg": "点赞操作成功"})
    if device_list:
        for device in device_list:
            driver = device_dict.get(device)
            if driver:
                driver.stop = False
                pool.submit(driver.find_given_gift, gift_name, count, giftInterval_list)
        return jsonify({"code": 0, "msg": "批量点赞操作成功"})


@app.route('/api/deviceList', methods=['GET'])
def get_user():
    device_list = []
    device_status = {}
    for device, driver in device_dict.items():
        device_list.append(device)
        device_status[device] = driver.status
    return jsonify({"device_list": device_list, "device_status": device_status})

@app.route('/api/handleApp', methods=['POST'])
def start_app():
    pool = ThreadPoolExecutor(20)
    data = request.get_json()
    handle = data.get("handle")
    if str(handle).lower() not in ["start", "stop"]:
        return jsonify({"code": -1, "msg": f"输入错误，没有【{handle}】这样的操作"})
    if not handle:
        return jsonify({"code": -1, "msg": f"请选择你的操作"})
    device = data.get("device")
    device_list = data.get("deviceList")
    if device and device_list:
        return jsonify({"code": -1, "msg": f"【批量操作】和【单一操作】只能任选一个，不能都选择"})
    if device is None and device_list is None:
        return jsonify({"code": -1, "msg": f"设备端口号不能为空"})
    # 如果是停止app
    if handle == "stop":
        # 单一操作
        if device:
            driver = device_dict.get(device)
            if not driver:
                return jsonify({"code": -1, "msg": f"没有找到端口为【{device}】的设备"})
            driver.app_stop()
            return jsonify({"code": 0, "msg": "操作成功，应用已关闭"})
        # 批量操作
        if device_list:
            for device in device_list:
                driver = device_dict.get(device)
                if driver:
                    pool.submit(driver.app_stop)
            return jsonify({"code": 0, "msg": "批量操作成功，应用已关闭"})
    else:
        tasks = []
        if device:
            driver = device_dict.get(device)
            if not driver:
                return jsonify({"code": -1, "msg": f"没有找到端口为【{device}】的设备"})
            driver.stop = False
            tasks.append(pool.submit(driver.app_start))
        if device_list:
            for device in device_list:
                driver = device_dict.get(device)
                driver.stop = False
                if driver:
                    tasks.append(pool.submit(driver.app_start))

        all_device_dict = {}
        for future in as_completed(tasks):
            try:
                result = future.result()
                if result:
                    cur_device = result['device']
                    cur_name = result['name']
                    all_device_dict[cur_device] = cur_name
            except Exception as e:
                print(e)
                pass
        pool.shutdown(True)
        print("所有线程已完成")
        return jsonify({"code": 0, "msg": "操作成功", "deviceMap": all_device_dict})


@app.route('/api/stopRun', methods=['POST'])
def stop_run():
    data = request.get_json()
    device = data.get('device')
    device_list = data.get("device_list")
    if device and device_list:
        return jsonify({"code": -1, "msg": f"【批量操作】和【单一操作】只能任选一个，不能都选择"})
    if device is None and device_list is None:
        return jsonify({"code": -1, "msg": f"设备端口号不能为空"})

    if device:
        driver = device_dict[device]
        driver.stop = True

    if device_list:
        for device in device_list:
            driver = device_dict[device]
            driver.stop = True

    return jsonify({"code": 0, "msg": "任务已停止"})


@app.route('/api/name', methods=['POST'])
def get_douyin_name():
    pool = ThreadPoolExecutor(20)
    data = request.get_json()
    device = data.get("device")
    device_list = data.get("deviceList")
    if device and device_list:
        return jsonify({"code": -1, "msg": f"【批量操作】和【单一操作】只能任选一个，不能都选择"})
    if device is None and device_list is None:
        return jsonify({"code": -1, "msg": f"设备端口号不能为空"})

    tasks = []
    if device:
        driver = device_dict.get(device)
        if not driver:
            return jsonify({"code": -1, "msg": f"没有找到端口为【{device}】的设备"})
        driver.stop = False
        tasks.append(pool.submit(driver.get_douyin_name))
    if device_list:
        for device in device_list:
            driver = device_dict.get(device)
            if driver:
                driver.stop = False
                tasks.append(pool.submit(driver.get_douyin_name))

    all_device_dict = {}
    for future in as_completed(tasks):
        try:
            result = future.result()
            if result:
                cur_device = result['device']
                cur_name = result['name']
                all_device_dict[cur_device] = cur_name
        except Exception as e:
            print(e)
            pass
    pool.shutdown(True)
    print("所有线程已完成")
    print("deviceMap->", all_device_dict)
    return jsonify({"code": 0, "msg": "操作成功", "deviceMap": all_device_dict})

# 根据直播间名称，找到直播间，并进入
@app.route('/api/findRoom', methods=['POST'])
def find_room():
    pool = ThreadPoolExecutor(10)
    data = request.get_json()
    room_name = data.get("roomName")
    device = data.get("device")
    device_list = data.get("deviceList")
    contain = data.get("contain")
    if not room_name:
        return jsonify({"code": -1, "msg": "房间名不能为空"})
    if device and device_list:
        return jsonify({"code": -1, "msg": f"【批量操作】和【单一操作】只能任选一个，不能都选择"})
    if not device and not device_list:
        return jsonify({"code": -1, "msg": f"设备端口号不能为空"})
    if device:
        driver = device_dict[device]
        if not driver:
            return jsonify({"code": -1, "msg": f"没有端口号为【{device}】的设备"})
        driver.stop = False
        pool.submit(driver.find_room, room_name)
        return jsonify({"code": 0, "msg": "指令下达成功，正在寻找直播间"})

    if device_list:
        for device in device_list:
            driver = device_dict.get(device)
            if driver:
                driver.stop = False
                pool.submit(driver.find_room, room_name, contain)
        return jsonify({"code": 0, "msg": "批量操作成功，正在寻找直播间"})


# 给主播点关注
@app.route('/api/clickCare', methods=['POST'])
def click_Care():
    pool = ThreadPoolExecutor(10)
    data = request.get_json()
    device = data.get("device")
    device_list = data.get("deviceList")
    if not device_list and not device:
        return jsonify({"code": -1, "msg": "设备端口号不能为空"})
    if device_list and device:
        return jsonify({"code": -1, "msg": f"【批量操作】和【单一操作】只能任选一个，不能都选择"})
    if device:
        driver = device_dict[device]
        driver.stop = False
        pool.submit(driver.click_care)
        return jsonify({"code": -1, "msg": "点赞操作成功"})
    if device_list:
        for device in device_list:
            driver = device_dict.get(device)
            if driver:
                driver.stop = False
                pool.submit(driver.click_care)
        return jsonify({"code": 0, "msg": "批量点赞操作成功"})



# 给直播间评论
@app.route('/api/sendText', methods=['POST', 'GET'])
def send_text():
    data = request.get_json()
    return global_send_text(data)

# 给直播间点赞
@app.route('/api/clickLike', methods=['POST', 'GET'])
def room_click_like():
    data = request.get_json()
    return global_room_click_like(data)

# 给直播间送礼物
@app.route('/api/findGift', methods=['POST', 'GET'])
def find_gift():
    data = request.get_json()
    return global_find_gift(data)

# 给直播间送礼物
@app.route('/api/loopHandle', methods=['POST'])
def loop_handle():
    pool = ThreadPoolExecutor(20)
    data = request.get_json()
    func_number = data.get("loopNumber")
    if len(func_number) != 3:
        return jsonify({"code": -1, "err": "循环的操作步骤有错，请输入正确的步骤"})
    device = data.get("device")
    device_list = data.get("deviceList")
    if not device_list and not device:
        return jsonify({"code": -1, "msg": "设备端口号不能为空"})
    if device_list and device:
        return jsonify({"code": -1, "msg": f"【批量操作】和【单一操作】只能任选一个，不能都选择"})

    # 评论请求参数
    text = data.get("text")
    textCount = data.get("textCount") or 1
    textInterval = data.get("textInterval") or 0.5
    try:
        textCount = int(textCount)
        textInterval = round(float(textInterval), 1)
    except Exception as e:
        print(e)
        return jsonify({"code": -1, "msg": f"【评论次数】 或 【评论频率】 输入错误", "err": f"【评论次数】 或 【评论频率】 输入错误"})
    text_params = {"input_text": text, "count": textCount, "interval": textInterval}

    # 点赞请求参数
    likeCount = data.get("likeCount")
    likeInterval = data.get("likeInterval") or 1
    randomInterval = data.get("randomInterval")
    try:
        likeCount = int(likeCount)
        likeInterval = round(float(likeInterval), 1) or 0
    except Exception as e:
        print(e)
        return jsonify({"code": -1, "msg": f"【点赞次数】 或 【点赞固定频率】 输入错误", "err": f"【点赞次数】 或 【点赞固定频率】 输入错误"})
    randomInterval_range = []
    if randomInterval:
        cur_range = str(randomInterval).split(",")
        print("range", cur_range)
        if len(cur_range) != 2:
            return jsonify({"code": -1, "msg": "输入错误，点赞随机范围必须是两个数", "err": "输入错误，点赞随机范围必须是两个数"})
        try:
            randomInterval_range.append(int(cur_range[0]))
            randomInterval_range.append(int(cur_range[1]))
        except Exception as e:
            print(e)
            return jsonify({"code": -1, "msg": "输入错误，点赞随机频率必须是数字", "err": "输入错误，点赞随机频率必须是数字"})
    like_params = {"count": likeCount, "interval": likeInterval, "random_interval": randomInterval}
    # 送礼物的请求参数
    gift_name = data.get("giftName")
    giftCount = data.get("giftCount") or 1
    giftInterval_list = data.get("giftIntervalList")
    if not gift_name:
        return jsonify({"code": -1, "msg": f"礼物名称不能为空", "err": f"礼物名称不能为空"})
    try:
        giftCount = int(giftCount)
        giftInterval_list = list(giftInterval_list)
    except Exception as e:
        print(e)
        return jsonify({"code": -1, "msg": f"【礼物个数】 或 【礼物时间间隔】 输入错误", "err": f"【礼物个数】 或 【礼物时间间隔】 输入错误"})
    gift_params = {"gift_name": gift_name, "count": giftCount, "giftInterval_list": giftInterval_list}

    params_dict = {
        "5": text_params,
        "6": like_params,
        "7": gift_params,
    }
    print("all_params-->", params_dict)
    tasks = []
    fail_device_list = []
    if device:
        driver = device_dict[device]
        driver.stop = False
        tasks.append(pool.submit(driver.loop_handle, func_number, params_dict))

    if device_list:
        for device in device_list:
            driver = device_dict.get(device)
            if driver:
                driver.stop = False
                tasks.append(pool.submit(driver.loop_handle, func_number, params_dict))

    for future in as_completed(tasks):
        try:
            result = future.result()
            if not result:
                continue
            if result.get("err"):
                fail_device_list.append(result.get("device"))
        except Exception as e:
            print(e)
            pass
    pool.shutdown(True)
    print("所有线程已完成")
    print("fail_device_list", fail_device_list)
    return jsonify({"code": 0, "msg": "操作成功", "fail_device_list": fail_device_list})

def send_text_params_handle(task_obj):
    """处理评论参数，看是否有错误"""
    taskType = task_obj.get("taskType")
    taskNumber = task_obj.get("taskNumber")
    cur_num = f"{taskType}.{taskNumber}"
    params = task_obj.get("params")
    text = params.get("text")
    textCount = params.get("count") or 1
    textInterval = params.get("interval") or 0.5
    try:
        textCount = int(textCount)
        textInterval = round(float(textInterval), 1)
    except Exception as e:
        print(e)
        return {"result": None, "err": f"{cur_num}: 【评论次数】 或 【评论频率】 输入错误"}

    text_params = {"input_text": text, "count": textCount, "interval": textInterval}
    return {"result": text_params, "err": None}


def click_like_params_handle(task_obj):
    """处理点赞参数，看是否输入正确"""
    taskType = task_obj.get("taskType")
    taskNumber = task_obj.get("taskNumber")
    cur_num = f"{taskType}.{taskNumber}"
    params = task_obj.get("params")
    likeCount = params.get("count")
    likeInterval = params.get("interval") or 1
    randomInterval = params.get("randomInterval")
    try:
        likeCount = int(likeCount)
        likeInterval = round(float(likeInterval), 1) or 0
    except Exception as e:
        print(e)
        return {"result": None, "err": f"{cur_num}: 【点赞次数】 或 【点赞固定频率】 输入错误"}
    randomInterval_range = []
    if randomInterval:
        if len(randomInterval) != 2:
            return {"result": None, "err": f"{cur_num}: 输入错误，点赞随机范围必须是两个数"}
        try:
            randomInterval_range.append(int(randomInterval[0]))
            randomInterval_range.append(int(randomInterval[1]))
        except Exception as e:
            print(e)
            return {"result": None, "err": f"{cur_num}: 输入错误，点赞随机频率必须是数字"}
    like_params = {"count": likeCount, "interval": likeInterval, "random_interval": randomInterval}
    return {"result": like_params, "err": None}


def find_gift_params_handle(task_obj):
    """处理送礼物任务的参数"""
    taskType = task_obj.get("taskType")
    taskNumber = task_obj.get("taskNumber")
    cur_num = f"{taskType}.{taskNumber}"
    params = task_obj.get("params")
    gift_name = params.get("name")
    giftCount = params.get("count") or 1
    giftInterval_list = params.get("interval")
    if not gift_name:
        return {"result": None, "err": f"{cur_num}: 礼物名称不能为空"}
    try:
        giftCount = int(giftCount)
        giftInterval_list = list(giftInterval_list)
    except Exception as e:
        print(e)
        return {"result": None, "err": f"{cur_num}: 【礼物个数】 或 【礼物时间间隔】 输入错误"}
    gift_params = {"gift_name": gift_name, "count": giftCount, "giftInterval_list": giftInterval_list}
    return {"result": gift_params, "err": None}

@app.route('/api/runTask', methods=['POST'])
def run_task_queue():
    data = request.get_json()
    print(data)
    if (len(data) < 1):
        return jsonify({"code": -1, "fatal": "任务队列不能为空"})
    pool = ThreadPoolExecutor(20)
    tasks = []
    handle_dict = {
        "5": send_text_params_handle,
        "6": click_like_params_handle,
        "7": find_gift_params_handle
    }
    for device_obj in data:
        device = device_obj.get("device")
        taskList = device_obj.get('taskList')
        cur_task_list = []
        for task in taskList:
            taskType = task['taskType']
            handle_func = handle_dict[taskType]
            res = handle_func(task)
            if res.get("err"):
                return jsonify({"code": -1, "fatal": res['err']})
            cur_task_obj = {"task_type": taskType, "params": res['result']}
            cur_task_list.append(cur_task_obj)
        driver = device_dict[device]
        driver.stop = False
        tasks.append(pool.submit(driver.run_task_queue, cur_task_list))

    fail_device_list = []
    for future in as_completed(tasks):
        try:
            result = future.result()
            if not result:
                continue
            print("当前res--->", result)
            if result.get("err"):
                fail_device_list.append(result.get("device"))
        except Exception as e:
            print(e)
            pass
    pool.shutdown(True)
    print("所有线程已完成")
    print("fail_device_list", fail_device_list)
    return jsonify({"code": 0, "msg": "操作成功", "fail_device_list": fail_device_list})



if __name__ == '__main__':
    app.run()